package com.peach.inquiry.imsdk;

import android.content.Context;

import com.peach.inquiry.IM;
import com.peach.inquiry.R;
import com.peach.inquiry.imsdk.tim.conversation.ConversationBean;
import com.peach.inquiry.imsdk.tim.conversation.ConversationUtil;
import com.peach.inquiry.imsdk.tim.conversation.IConversationListener;
import com.peach.inquiry.imsdk.tim.ITimUserStatusListener;
import com.peach.inquiry.imsdk.tim.message.IMsgListener;
import com.peach.inquiry.imsdk.tim.message.MsgBean;
import com.peach.inquiry.imsdk.tim.message.MsgUtil;
import com.tencent.imsdk.v2.V2TIMAdvancedMsgListener;
import com.tencent.imsdk.v2.V2TIMCallback;
import com.tencent.imsdk.v2.V2TIMConversation;
import com.tencent.imsdk.v2.V2TIMConversationListener;
import com.tencent.imsdk.v2.V2TIMConversationResult;
import com.tencent.imsdk.v2.V2TIMManager;
import com.tencent.imsdk.v2.V2TIMMessage;
import com.tencent.imsdk.v2.V2TIMMessageReceipt;
import com.tencent.imsdk.v2.V2TIMSDKConfig;
import com.tencent.imsdk.v2.V2TIMSDKListener;
import com.tencent.imsdk.v2.V2TIMSendCallback;
import com.tencent.imsdk.v2.V2TIMValueCallback;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * 腾讯IM工具类
 *
 * @author Wongxd
 */
public class TimManager {

    private static TimManager mCloudManage;

    //用户状态
    private ITimUserStatusListener mUserStatusListener;

    //会话状态
    private IConversationListener mConversationListener;

    //消息状态
    private IMsgListener mMsgListener;


    private V2TIMAdvancedMsgListener mV2TIMAdvancedMsgListener;


    private TimManager() {

        mV2TIMAdvancedMsgListener = new V2TIMAdvancedMsgListener() {
            @Override
            public void onRecvNewMessage(V2TIMMessage msg) {
                super.onRecvNewMessage(msg);
                LogUtil.e("消息监听 新消息  " + msg.getNickName());
                //
                if (mMsgListener != null) {
                    mMsgListener.newMsg(msg);
                }
            }

            @Override
            public void onRecvC2CReadReceipt(List<V2TIMMessageReceipt> receiptList) {
                super.onRecvC2CReadReceipt(receiptList);
                //receiptList	已读回执列表  todo 消息已读通知 flutter？
                LogUtil.e("消息监听  收到 C2C 消息已读回执  ");
            }

            @Override
            public void onRecvMessageRevoked(String msgID) {
                super.onRecvMessageRevoked(msgID);
                // todo 消息撤回
                LogUtil.e("消息监听  收到消息撤回的通知  " + msgID);
            }
        };
    }

    public static TimManager getInstance() {
        if (mCloudManage == null) {
            synchronized (TimManager.class) {
                if (mCloudManage == null) {
                    mCloudManage = new TimManager();
                }
            }
        }
        return mCloudManage;
    }

    /**
     * 初始化
     */
    public void initTIM(int timAppID) {


        initConversationListener();

        initAdvancedMsgListener();


        // 1. 从 IM 控制台获取应用 SDKAppID，详情请参考 SDKAppID。
        // 2. 初始化 config 对象
        V2TIMSDKConfig config = new V2TIMSDKConfig();
        // 3. 指定 log 输出级别，详情请参考 SDKConfig。
        config.setLogLevel(V2TIMSDKConfig.V2TIM_LOG_INFO);
        // 4. 初始化 SDK 并设置 V2TIMSDKListener 的监听对象。
        // initSDK 后 SDK 会自动连接网络，网络连接状态可以在 V2TIMSDKListener 回调里面监听。
        V2TIMManager.getInstance()
                .initSDK(
                        IM.staticContext.getApplicationContext(),
                        timAppID,
                        config,
                        new V2TIMSDKListener() {
                            // 5. 监听 V2TIMSDKListener 回调
                            @Override
                            public void onConnecting() {
                                // 正在连接到腾讯云服务器
                                LogUtil.e("IM正在连接到腾讯云服务器");
                            }

                            @Override
                            public void onConnectSuccess() {
                                // 已经成功连接到腾讯云服务器
                                LogUtil.e("IM连接成功");
                                if (mUserStatusListener != null) {
                                    mUserStatusListener.onConnectStatus(0);
                                }
                            }

                            @Override
                            public void onConnectFailed(int code, String error) {
                                // 连接腾讯云服务器失败
                                LogUtil.e("IM连接已断开");
                                if (mUserStatusListener != null) {
                                    mUserStatusListener.onConnectStatus(code);
                                }
                            }
                        });

    }


    /**
     * 设置用户状态监听
     *
     * @param listener
     */
    public void setUserStatusListener(ITimUserStatusListener listener) {
        this.mUserStatusListener = listener;
    }


    /**
     * 设置会话监听
     *
     * @param listener
     */
    public void setConversationListener(IConversationListener listener) {
        mConversationListener = listener;
    }


    /**
     * 设置消息监听
     *
     * @param listener
     */
    public void setMsgListener(IMsgListener listener) {
        mMsgListener = listener;
    }

    /**
     * 进行IM登录操作
     */
    public void login(String identify, String userSign) {
        V2TIMManager.getInstance().login(identify, userSign, new V2TIMCallback() {
            @Override
            public void onError(int i, String s) {
                LogUtil.e("IM登录失败 " + i + "  " + s);
                if (mUserStatusListener != null) {
                    mUserStatusListener.onUserLoginListener(i, s);
                }
            }

            @Override
            public void onSuccess() {
                LogUtil.e("IM登录成功");
                //登录成功
                if (mUserStatusListener != null) {
                    mUserStatusListener.onUserLoginListener(V2TIMManager.V2TIM_STATUS_LOGINED, "");
                }
            }
        });
    }

    /**
     * 获取登录状态
     * <p>
     * <p>
     * 登录状态
     * V2TIM_STATUS_LOGINED 已登录
     * V2TIM_STATUS_LOGINING 登录中
     * V2TIM_STATUS_LOGOUT 无登录
     *
     * @return 1-已登录
     */
    public int getLoginStatus() {
        return V2TIMManager.getInstance().getLoginStatus();
    }

    /**
     * 获取登录用户
     *
     * @return 用户name
     */
    public String getLoginUser() {
        return V2TIMManager.getInstance().getLoginUser();
    }

    /**
     * 退出登录
     */
    public void logout() {
        V2TIMManager.getInstance().logout(new V2TIMCallback() {
            @Override
            public void onError(int i, String s) {
                LogUtil.e("退出失败  " + i + "  " + s);
            }

            @Override
            public void onSuccess() {
                LogUtil.e("退出成功");
                if (mUserStatusListener != null) {
                    mUserStatusListener.onUserStatus(0);
                }
            }
        });
    }


    /**
     * 初始化时，调用此方法
     */
    public void initConversationListener() {
        V2TIMManager.getConversationManager().setConversationListener(new V2TIMConversationListener() {
            @Override
            public void onSyncServerStart() {
                super.onSyncServerStart();
                LogUtil.e("会话监听 同步开始  ");
            }

            @Override
            public void onSyncServerFinish() {
                super.onSyncServerFinish();
                LogUtil.e("会话监听 同步结束  ");
            }

            @Override
            public void onSyncServerFailed() {
                super.onSyncServerFailed();
                LogUtil.e("会话监听 同步失败  ");
            }

            @Override
            public void onNewConversation(List<V2TIMConversation> conversationList) {
                super.onNewConversation(conversationList);
                LogUtil.e("会话监听 有新会话  " + conversationList.size());
            }

            @Override
            public void onConversationChanged(List<V2TIMConversation> conversationList) {
                super.onConversationChanged(conversationList);
                LogUtil.e("会话监听 会话改变  " + conversationList.size());
                if (mConversationListener != null) {
                    ArrayList<ConversationBean> newList = ConversationUtil.V2TIMConversationList2ConversationBeanList(conversationList);
                    mConversationListener.refresh(newList);
                }
            }
        });
    }

    /**
     * 获取会话列表
     * <p>
     * 一个会话对应一个聊天窗口，比如跟一个好友的 1v1 聊天，或者一个聊天群，都是一个会话。
     * 由于历史的会话数量可能很多，所以该接口希望您采用分页查询的方式进行调用。
     * 该接口拉取的是本地缓存的会话，如果服务器会话有更新，SDK 内部会自动同步，然后在 V2TIMConversationListener 回调告知客户。
     * 该接口获取的会话列表默认已经按照会话 lastMessage -> timestamp 做了排序，timestamp 越大，会话越靠前。
     * 如果会话全部拉取完毕，成功回调里面 V2TIMConversationResult 中的 isFinished 获取字段值为 true。
     * 最多能拉取到最近的5000个会话。
     * 参数
     *
     * @param nextSeq 分页拉取的游标，第一次默认取传 0，后续分页拉传上一次分页拉取成功回调里的 nextSeq
     * @param count   分页拉取的个数，一次分页拉取不宜太多，会影响拉取的速度，建议每次拉取 100 个会话
     */
    public void getConversationList(long nextSeq, int count) {
        V2TIMManager.getConversationManager().getConversationList(nextSeq, count, new V2TIMValueCallback<V2TIMConversationResult>() {
            @Override
            public void onError(int i, String s) {
                LogUtil.e("获取会话列表失败  " + i + "  " + s);
            }

            @Override
            public void onSuccess(V2TIMConversationResult v2TIMConversationResult) {
                LogUtil.e("获取会话列表成功  " + v2TIMConversationResult.getConversationList().size());
                LogUtil.e("获取会话列表成功  getNextSeq" + v2TIMConversationResult.getNextSeq());
                if (mConversationListener != null) {
                    ArrayList<ConversationBean> newList = ConversationUtil.V2TIMConversationList2ConversationBeanList(v2TIMConversationResult.getConversationList());
                    mConversationListener.setNextSeq(v2TIMConversationResult.getNextSeq());
                    mConversationListener.refresh(newList);
                }
            }
        });
    }


    /**
     * 获取会话
     *
     * @param conversationID 会话id
     */
    public void getConversation(String conversationID) {
        V2TIMManager.getConversationManager().getConversation(conversationID, new V2TIMValueCallback<V2TIMConversation>() {
            @Override
            public void onError(int i, String s) {
                LogUtil.e("获取会话 失败  " + i + "  " + s);
            }

            @Override
            public void onSuccess(V2TIMConversation v2TIMConversation) {
                LogUtil.e("获取会话成功  " + v2TIMConversation.getShowName());
            }
        });
    }


    public void initAdvancedMsgListener() {
        V2TIMManager.getMessageManager().addAdvancedMsgListener(mV2TIMAdvancedMsgListener);
    }

    public void removeAdvancedMsgListener() {
//        V2TIMManager.getMessageManager().removeAdvancedMsgListener(mV2TIMAdvancedMsgListener);
    }

    public Map<String, V2TIMMessage> chatLastMsgByUserIDMap = new HashMap<>();

    /**
     * 获取单聊历史消息
     * <p>
     * 参数
     *
     * @param userID    对方用户ID
     * @param count     拉取消息的个数，不宜太多，会影响消息拉取的速度，这里建议一次拉取 20 个
     * @param firstPull 是否是第一次拉取
     *                  <p>
     *                  lastMsg	获取消息的起始消息，如果传 null，起始消息为会话的最新消息
     *                  <p>
     *                  注意
     *                  如果 SDK 检测到没有网络，默认会直接返回本地数据
     */
    public void getC2CHistoryMsgList(final String userID, final int count, boolean firstPull) {
        // 获取下一次分页拉取的起始消息
        V2TIMMessage lastMsg = null;
        lastMsg = chatLastMsgByUserIDMap.get(userID);

        // 第一次拉取 lastMsg 传 null，表示从最新的消息开始拉取 count 条消息
        V2TIMManager.getMessageManager().getC2CHistoryMessageList(userID, count, firstPull ? null : lastMsg, new V2TIMValueCallback<List<V2TIMMessage>>() {
            @Override
            public void onError(int code, String desc) {
                // 拉取失败
                LogUtil.e("获取单聊历史消息 失败  " + code + "  " + desc);
                if (mMsgListener != null) {
                    mMsgListener.refreshChatUI(null);
                }
            }

            @Override
            public void onSuccess(List<V2TIMMessage> v2TIMMessages) {
                LogUtil.e("获取单聊历史消息 成功  " + v2TIMMessages.size());
                // 分页拉取返回的消息默认是按照从新到旧排列
                if (v2TIMMessages.size() > 0) {
                    // 获取下一次分页拉取的起始消息
                    V2TIMMessage lastMsg = v2TIMMessages.get(v2TIMMessages.size() - 1);
                    chatLastMsgByUserIDMap.put(userID, lastMsg);
                    //通知listener
                    if (mMsgListener != null) {
                        mMsgListener.refreshChatUI(v2TIMMessages);
                    }
                } else {
                    mMsgListener.refreshChatUI(null);
                }
            }
        });
    }


    private void getMsgByMsgID(String msgID) {
        //todo 文档上有通过消息ID 获取消息的方法，但是在SDK里没找到
    }


    /**
     * 设置单聊消息已读
     *
     * @param userID
     */
    public void markC2CMessageAsRead(String userID) {
        V2TIMManager.getMessageManager().markC2CMessageAsRead(userID, new V2TIMCallback() {
            @Override
            public void onError(int i, String s) {
                LogUtil.e("设置单聊消息已读 失败   " + i + "   " + s);
            }

            @Override
            public void onSuccess() {
                LogUtil.e("设置单聊消息已读 成功");
            }
        });
    }

    /**
     * 发送文字消息
     *
     * @param targetUserID 接收者ID
     * @param content      文字内容
     * @param customMsgID  自定义消息ID，flutter端生成，用于更新flutter UI中消息状态（成功，进度，失败）
     */
    public void sendTextMsg(String targetUserID, String content, final String customMsgID) {
        // 创建消息
        V2TIMMessage v2TIMMessage = V2TIMManager.getMessageManager().createTextMessage(content);
        v2TIMMessage.setLocalCustomData(customMsgID);
        // 发送消息
        doSendMsg(v2TIMMessage, targetUserID, customMsgID);
    }


    /**
     * 发送自定义（卡片、hint）消息
     *
     * @param targetUserID 接收者ID
     * @param content      自定义内容
     * @param customMsgID  自定义消息ID，flutter端生成，用于更新flutter UI中消息状态（成功，进度，失败）
     */
    public void sendCustomMsg(String targetUserID, String content, final String customMsgID) {
        // 创建消息
        V2TIMMessage v2TIMMessage = V2TIMManager.getMessageManager().createCustomMessage(content.getBytes());
        v2TIMMessage.setLocalCustomData(customMsgID);
        // 发送消息
        doSendMsg(v2TIMMessage, targetUserID, customMsgID);
    }


    /**
     * 发送表情消息
     *
     * @param targetUserID 接收者ID
     * @param faceData     表情内容
     * @param customMsgID  自定义消息ID，flutter端生成，用于更新flutter UI中消息状态（成功，进度，失败）
     */
    public void sendFaceMsg(String targetUserID, String faceData, final String customMsgID) {
        // 创建消息
        V2TIMMessage v2TIMMessage = V2TIMManager.getMessageManager().createFaceMessage(0, faceData.getBytes());
        v2TIMMessage.setLocalCustomData(customMsgID);
        // 发送消息
        doSendMsg(v2TIMMessage, targetUserID, customMsgID);
    }


    /**
     * 发送图片消息
     *
     * @param targetUserID 接收者ID
     * @param imgPath      图片路径
     * @param customMsgID  自定义消息ID，flutter端生成，用于更新flutter UI中消息状态（成功，进度，失败）
     */
    public void sendImgMsg(String targetUserID, String imgPath, final String customMsgID) {
        // 创建图片消息
        V2TIMMessage v2TIMMessage = V2TIMManager.getMessageManager().createImageMessage(imgPath);
        v2TIMMessage.setLocalCustomData(customMsgID);
        // 发送图片消息
        doSendMsg(v2TIMMessage, targetUserID, customMsgID);
    }


    /**
     * 发送语音消息
     *
     * @param targetUserID  接收者ID
     * @param voicePath     语音路径
     * @param voiceDuration 语音时长
     * @param customMsgID   自定义消息ID，flutter端生成，用于更新flutter UI中消息状态（成功，进度，失败）
     */
    public void sendVoiceMsg(String targetUserID, String voicePath, int voiceDuration, final String customMsgID) {
        // 创建消息
        V2TIMMessage v2TIMMessage = V2TIMManager.getMessageManager().createSoundMessage(voicePath, voiceDuration);
        v2TIMMessage.setLocalCustomData(customMsgID);
        doSendMsg(v2TIMMessage, targetUserID, customMsgID);
    }

    /**
     * 发送高级消息（高级版本：可以指定优先级，推送信息等特性）
     * <p>
     * 参数
     *
     * @param msg         待发送的消息对象，需要通过对应的 createXXXMessage 接口进行创建。
     * @param receiver    消息接收者的 userID, 如果是发送 C2C 单聊消息，只需要指定 receiver 即可。
     * @param customMsgID 自定义消息ID，flutter端生成，用于更新flutter UI中消息状态（成功，进度，失败）
     *                    <p>
     *                    <p>
     *                    <p>
     *                    groupID	目标群组 ID，如果是发送群聊消息，只需要指定 groupID 即可。
     *                    priority	消息优先级，仅针对群聊消息有效。请把重要消息设置为高优先级（比如红包、礼物消息），高频且不重要的消息设置为低优先级（比如点赞消息）。
     *                    onlineUserOnly	是否只有在线用户才能收到，如果设置为 true ，接收方历史消息拉取不到，常被用于实现“对方正在输入”或群组里的非重要提示等弱提示功能。
     *                    offlinePushInfo	离线推送时携带的标题和内容。
     *                    返回
     *                    消息唯一标识
     *                    注意
     *                    设置 offlinePushInfo 字段，需要先在 V2TIMOfflinePushManager 开启推送。推送开启后，除了自定义消息，其他消息默认都会推送。
     *                    自定义消息默认不会推送，如果需要推送，请设置 offlinePushInfo 的 desc 字段，推送的时候会默认展示 desc 信息。
     *                    <p>
     */
    public void doSendMsg(V2TIMMessage msg, String receiver, final String customMsgID) {
        // 发送消息
        V2TIMManager.getMessageManager().sendMessage(msg, receiver,
                null,
                V2TIMMessage.V2TIM_PRIORITY_DEFAULT,
                false,
                null,
                new V2TIMSendCallback<V2TIMMessage>() {
                    @Override
                    public void onError(int code, String desc) {
                        // 消息发送失败
                        LogUtil.e("customMsgID: " + customMsgID + "  消息发送失败  " + code + "  " + desc);
                        if (mMsgListener != null) {
                            mMsgListener.sendFailed(customMsgID, desc);
                        }
                    }

                    @Override
                    public void onSuccess(V2TIMMessage v2TIMMessage) {
                        // 消息发送成功
                        LogUtil.i("customMsgID: " + customMsgID + "  消息发送成功  ");
                        //
                        if (mMsgListener != null) {
                            v2TIMMessage.setLocalCustomData(customMsgID);
                            mMsgListener.newMsg(v2TIMMessage);
                        }
                    }

                    @Override
                    public void onProgress(int progress) {
                        // 发送进度（0-100）
                        LogUtil.i("customMsgID: " + customMsgID + "  发送进度  " + progress);
                        if (mMsgListener != null) {
                            mMsgListener.sendProgress(customMsgID, progress);
                        }
                    }
                });
    }


}
